﻿using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEngine.AI;


public enum WarFlagState
{
    None,Move,Attack,Skill1,Skill2
}



public class WarFlag : MonoBehaviour {
    public VRControllerInteractive controllerInteractive;
    public ControllerPadCommandInteractive padCommandInteractive;
    public BeamRayInteractive beamRayInteractive;
    public WarFlagOrigin origin;
    public TextMesh Test_textmesh;
    public DotLineRender OriginDotLineRender;
    public DotLineRender PointingAtTargetLineRender;

    //探测最近敌人部队时要求敌人的最短距离
    public float SenseEnemyTroopLeaderMinRange;


    public TroopLeader targetTroopLeader;
    public WarFlagState chosenState;
    public WarFlagState attachedState;
    public bool isAttach;
    //旗帜可以附着在Transform上，也可以固定在一个位置
    public Vector3 AttachFixedPos;
    public Quaternion AttachFixedRotation;
    public Transform AttachTrans;
    public Vector3 AttachPos 
    {
        get { return AttachTrans == null ? AttachFixedPos : AttachTrans.position; }
    }
    public Quaternion AttachRotation
    {
        get { return AttachTrans == null ? AttachFixedRotation : AttachTrans.rotation; }
    }

    public bool Test_Attach;



    private void Start()
    {
        controllerInteractive.StartHolding += HoldingControllerAddAction;
        controllerInteractive.ReleaseHolding += HoldingControllerReleaseAction;
        AttachFixedPos = transform.position;
        AttachFlag(this, new ClickedEventArgs());
    }

    void Update () {
        if(origin==null)
        {
            Destroy(this);
            return;
        }

        if(Test_Attach)
        {
            AttachFlag(this, new ClickedEventArgs());
            Test_Attach = false;
        }

        OriginDotLineRender.ResetPos(origin.transform.position, transform.position);
        if(controllerInteractive.isHolding)
        {
            OriginDotLineRender.isRender = true;
            isAttach = false;
            transform.position = controllerInteractive.controller.transform.position;
            transform.rotation = controllerInteractive.controller.transform.rotation;
            switch (padCommandInteractive.state)
            {
                case ControllerPadCommandState.UpLeft:
                    chosenState = chosenState = WarFlagState.Move;
                    break;
                case ControllerPadCommandState.UpRight:
                    chosenState = WarFlagState.Attack;
                    break;
                case ControllerPadCommandState.DownLeft:
                    chosenState = WarFlagState.Skill1;
                    break;
                case ControllerPadCommandState.DownRight:
                    chosenState = WarFlagState.Skill2;
                    break;
                case ControllerPadCommandState.None:
                    chosenState = WarFlagState.None;
                    break;
            }
            Test_textmesh.text = chosenState.ToString();
        }
        else
        {
            OriginDotLineRender.isRender = false;
            transform.position = AttachPos;
            transform.rotation = AttachRotation;
        }
        if(beamRayInteractive.hitRay!=null || origin.beamRayInteractive.hitRay!=null)
        {
            OriginDotLineRender.isRender = true;
        }

        TryGetNearestEnemyTroopLeader();
        if (targetTroopLeader != null && (controllerInteractive.isHolding || attachedState == WarFlagState.Attack))
        {
            PointingAtTargetLineRender.isRender = true;
            PointingAtTargetLineRender.ResetPos(transform.position, targetTroopLeader.centerPosition);
        }
        else
        {
            PointingAtTargetLineRender.isRender = false;
        }


        if (isAttach)
        {
            switch (attachedState)
            {
                case WarFlagState.Move:
                    break;
                case WarFlagState.Attack:
                    break;
            }

        }
    }


    private void HoldingControllerAddAction()
    {
        controllerInteractive.controller.PadClicked += AttachFlag;
    }

    private void HoldingControllerReleaseAction()
    {
        controllerInteractive.controller.PadClicked -= AttachFlag;
    }

    public void AttachFlag(object sender, ClickedEventArgs e)
    {
        if (isAttach) return;
        switch (chosenState)
        {
            case WarFlagState.Move:
                AttachState(WarFlagState.Move);
                break;
            case WarFlagState.Attack:
                AttachState(WarFlagState.Attack);
                break;
            case WarFlagState.Skill1:
                AttachState(WarFlagState.Skill1);
                break;
        }
    }




    public void AttachState(WarFlagState state)
    {
        DisattachState(attachedState);
        attachedState = state;
        switch (state)
        {
            case WarFlagState.Move:
                FlagControllerAttach();
                AttachOnTerrain();

                //TroopReAssignFormation();

                origin.troopVehicle.targetPosition = AttachPos;
                origin.troopVehicle.targetRotation = AttachRotation;
                origin.troopLeader.vehicle.formationMove = true;

                break;
            case WarFlagState.Attack:
                if (targetTroopLeader != null)
                {
                    FlagControllerAttach();
                    AttachOnTarget();
                    origin.troopLeader.warrior.rangedAttackTarget = targetTroopLeader;

                    if(origin.troopLeader.centerPosition.DistanceGreaterThan(targetTroopLeader.troopCenter.position, origin.troopLeader.warrior.rangedAttackRange))
                    {
                        origin.troopLeader.vehicle.formationMove = true;
                        origin.troopVehicle.targetPosition = targetTroopLeader.troopCenter.position;
                    }
                }
                break;
            case WarFlagState.Skill1:
                FlagControllerAttach();
                AttachOnTerrain();
                origin.troopLeader.ChargeTo(AttachFixedPos);
                break;
                
        }
    }

    private void FlagControllerAttach()
    {
        isAttach = true;
        controllerInteractive.isHolding = false;
    }

    private void AttachOnTerrain()
    {
        RaycastHit terrainHit;
        Physics.Raycast(transform.position + 100 * Vector3.up, Vector3.down, out terrainHit, 1000f, LayerMask.GetMask(LayerNameSet.Terrain));
        transform.position = terrainHit.point;
        transform.rotation = Quaternion.LookRotation(Vector3.ProjectOnPlane(transform.forward, Vector3.up));
        AttachFixedRotation = transform.rotation;
        AttachTrans = null;
        AttachFixedPos = terrainHit.point;
    }

    private void AttachOnTarget()
    {
        AttachTrans = targetTroopLeader.troopCenter.transform;
    }

    public void DisattachState(WarFlagState state)
    {
        switch(state)
        {
            case WarFlagState.Attack:
                origin.troopLeader.warrior.rangedAttackTarget = null;
                AttachTrans = null;
                break;
        }
    }


    public void TroopReAssignFormation()
    {
        origin.troopVehicle.targetPosition = transform.position;
        origin.troopVehicle.targetRotation = transform.rotation;
    }


    private void TryGetNearestEnemyTroopLeader()
    {
        TroopLeader t= TroopLeaderManager.Instance.GetNearestTroopLeader(transform.position, PlayerType.AIEnemy);
        if(t!=null && t.transform.position.DistanceLessThan(transform.position, SenseEnemyTroopLeaderMinRange))
        {
            targetTroopLeader = t;
        }
        else
        {
            targetTroopLeader = null;
        }
    }
}
